#ifndef OBJECTBROWSER_IMPL_HXX
#define OBJECTBROWSER_IMPL_HXX

#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>

#include <com/sun/star/reflection/XIdlReflection.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>

#include <rtl/ustring.hxx>
#include <cppuhelper/implbase2.hxx>

#include <vcl/wrkwin.hxx>
#include <svtools/svtreebx.hxx>

#include <hash_map>

/* Object browser data structure,
   including data needed for drawing the tree
*/

namespace objectbrowser_impl {
    using com::sun::star::container::XNameContainer;
    using com::sun::star::uno::Reference;
    using com::sun::star::uno::Sequence;
    using com::sun::star::uno::XComponentContext;
    using com::sun::star::lang::XTypeProvider;
    using com::sun::star::lang::XServiceInfo;
    using com::sun::star::uno::Any;
    using com::sun::star::uno::Type;
    using com::sun::star::uno::RuntimeException;
    using com::sun::star::lang::IllegalArgumentException;
    using com::sun::star::lang::WrappedTargetException;
    using com::sun::star::container::ElementExistException;
    using com::sun::star::container::NoSuchElementException;
    using com::sun::star::reflection::XIdlReflection;
    using com::sun::star::reflection::XIdlClass;
    using com::sun::star::beans::XIntrospection;
    using com::sun::star::beans::XIntrospectionAccess;
    using rtl::OUString;
    using rtl::OUStringHash;
    class ObjectBrowserImpl
	: public ::cppu::WeakImplHelper2<XNameContainer,XServiceInfo>
    {
    public:
	ObjectBrowserImpl(const Reference<XComponentContext> & xContext);

	// XElementAccess
	Type getElementType() throw (RuntimeException);
	sal_Bool hasElements() throw (RuntimeException);

	// XNameAccess
	Any getByName(const OUString& aName) 
	    throw (NoSuchElementException, WrappedTargetException, 
		   RuntimeException);
	Sequence<OUString> getElementNames() 
	    throw (RuntimeException);
	sal_Bool hasByName(const OUString& aName) 
	    throw(RuntimeException);

	// XNameContainer
	void insertByName(const OUString& name, const Any& element) 
	    throw (IllegalArgumentException, ElementExistException, 
		   WrappedTargetException, 
		   RuntimeException);
	void removeByName(const OUString& name) 
	    throw (NoSuchElementException, WrappedTargetException, 
		   RuntimeException);

	// XNameReplace
	void replaceByName(const OUString& name, const Any& element)
	    throw (IllegalArgumentException, NoSuchElementException, 
		   WrappedTargetException, RuntimeException);
	
	// XServiceInfo
	OUString SAL_CALL getImplementationName()
	    throw (RuntimeException);
	sal_Bool SAL_CALL supportsService(OUString const & serviceName )
	    throw (RuntimeException);
	Sequence<OUString> SAL_CALL getSupportedServiceNames()
	    throw (RuntimeException);
    private:
	const Reference<XComponentContext> m_xContext;
	
	const Reference<XIdlReflection> reflection;
	const Reference<XIntrospection> introspection;

	WorkWindow w;
	SvTreeListBox tree;

	struct object_data {
	    const Any* obj;
	    SvLBoxEntry* tree_item;
	    Sequence<Reference<XIdlClass> > interfaces;
	    Reference<XIntrospectionAccess> inspect;
	};

	std::hash_map<OUString, object_data, OUStringHash> objects;
    };
}

#endif
